package org.budo.filestore.qiniu;

import java.io.InputStream;
import java.util.Map;

import org.budo.filestore.api.DownloadRequest;
import org.budo.filestore.api.FileMeta;
import org.budo.support.lang.util.IoUtil;
import org.budo.support.lang.util.NumberUtil;

import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;
import com.qiniu.util.Json;

/**
 * @author lmw
 *         {"hash":"Fg-SEAToQ8P8_bVmG8BQfrQI2CRu","fsize":29465,"putTime":15014927816464082,"mimeType":"image/jpeg"}
 *         {"size":1318,"format":"png","width":136,"height":73,"colorModel":"nrgba"}
 */
public class LazyLoadQiniuFileMeta implements FileMeta {
    private QiniuFileStore qiniuFileStore;

    private DownloadRequest downloadRequest;

    private FileInfo fileInfo;

    private Map<String, Object> imageInfo;

    public LazyLoadQiniuFileMeta(QiniuFileStore qiniuFileStore, DownloadRequest downloadRequest) {
        this.qiniuFileStore = qiniuFileStore;
        this.downloadRequest = downloadRequest;
    }

    public FileInfo getFileInfo() {
        if (null == this.fileInfo) {
            this.fileInfo = this.loadFileInfo();
        }
        return fileInfo;
    }

    public Map<String, Object> getImageInfo() {
        if (null == this.imageInfo) {
            this.imageInfo = this.loadImageInfo();
        }
        return imageInfo;
    }

    private FileInfo loadFileInfo() {
        try {
            Auth auth = Auth.create(qiniuFileStore.getAccessKey(), qiniuFileStore.getSecretKey());
            Configuration configuration = new Configuration();
            BucketManager bucketManager = new BucketManager(auth, configuration);
            return bucketManager.stat(qiniuFileStore.getBucketName(), downloadRequest.getContentUrl());
        } catch (Throwable e) {
            throw new RuntimeException("loadFileInfo error", e);
        }
    }

    private Map<String, Object> loadImageInfo() {
        DownloadRequest loadImageInfoRequest;
        String contentUrl = downloadRequest.getContentUrl();
        if (!contentUrl.endsWith("?imageInfo")) {
            contentUrl = contentUrl + "?imageInfo";
            QiniuDownloadRequest qiniuDownloadRequest = new QiniuDownloadRequest();
            qiniuDownloadRequest.setContentUrl(contentUrl);
            if (downloadRequest instanceof QiniuDownloadRequest) {
                qiniuDownloadRequest.setDownloadDomain(((QiniuDownloadRequest) downloadRequest).getDownloadDomain());
            }
            qiniuDownloadRequest.setAntiLeechDuration(120);
            loadImageInfoRequest = qiniuDownloadRequest;
        } else {
            loadImageInfoRequest = downloadRequest;
        }

        String responseBody;

        InputStream downloadStream = qiniuFileStore.downloadStream(loadImageInfoRequest);
        responseBody = new String(IoUtil.toByteArray(downloadStream));

        return Json.decode(responseBody).map();
    }

    @Override
    public Long getFileSize() {
        return this.getFileInfo().fsize;
    }

    @Override
    public Integer getImageHeight() {
        Double value = NumberUtil.toDouble(this.getImageInfo().get("height"));
        return null == value ? null : value.intValue();
    }

    @Override
    public Integer getImageWidth() {
        Double value = NumberUtil.toDouble(this.getImageInfo().get("width"));
        return null == value ? null : value.intValue();
    }

    public Map<String, Object> toImageInfo() {
        return this.getImageInfo();
    }
}